package see.battle.drawer;

import java.util.ArrayList;
import java.util.concurrent.Callable;

import see.battle.Const;
import see.battle.R;
import see.battle.gui.GameView;
import see.battle.object.ObjectPool.DrawProcessor;
import see.battle.object.ObjectPool.FireProcessor;
import see.battle.object.ObjectPool.MoveOcularProcessor;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.DisplayMetrics;

public class AndroidDrawer implements Drawer {
  
  private Resources _res;
  private Paint _p;
  private GameView _view;
  private int _widthInPx;
  private int _heightInPx;
  private Canvas _canvas;
  private int _firstShipId;
  private int _firstBulletId;
  private int _firstBgId;
  private int _firstFireId;
  private int _firstOcularId;
  private int _firstOpponentFocusId;
  private ArrayList<Bitmap> _images = new ArrayList<Bitmap>();
  
  public class CanvasSetter implements Callable<Object> {
    private Canvas _canvas;
    
    public void setCanvas(Canvas canvas) {
      _canvas = canvas;
    }

    //@Override
    public Object call() throws Exception {
      set_canvas(_canvas);
      return null;
    }
  }
  
  /**
   * @param res
   * @param metrics
   * @param view
   */
  public AndroidDrawer(Resources res, DisplayMetrics metrics, GameView view) {
    _res = res;
    _view = view;
    if (metrics != null) {
      _widthInPx = metrics.widthPixels;
      _heightInPx = metrics.heightPixels;
    }
    _view.set_widthInPx(_widthInPx);
    _view.set_heightInPx(_heightInPx);
    _view.set_canvasSetter(new CanvasSetter());
    initResources();
  }

  /* (non-Javadoc)
   * @see see.battle.Drawer#get_widthInPx()
   */
  public int get_widthInPx() {
    return _widthInPx;
  }

  /* (non-Javadoc)
   * @see see.battle.Drawer#get_heightInPx()
   */
  public int get_heightInPx() {
    return _heightInPx;
  }

  public void set_canvas(Canvas canvas) {
    _canvas = canvas;
  }

  private void initResources() {
    _p = new Paint();
    _p.setStrokeWidth(Const.statTextStrokeWidth);
    _p.setColor(Const.statTextColor);
    _p.setTextSize(Const.statTextSize);
    _p.setStyle(Paint.Style.FILL_AND_STROKE);
    _p.setAntiAlias(true);
    _firstShipId = _images.size();
    _images.add(BitmapFactory.decodeResource(_res, R.drawable.ship_1_left));
    _images.add(BitmapFactory.decodeResource(_res, R.drawable.ship_1_right));
    _images.add(BitmapFactory.decodeResource(_res, R.drawable.ship_2_left));
    _images.add(BitmapFactory.decodeResource(_res, R.drawable.ship_2_right));
    _images.add(BitmapFactory.decodeResource(_res, R.drawable.ship_3_left));
    _images.add(BitmapFactory.decodeResource(_res, R.drawable.ship_3_right));
    _images.add(BitmapFactory.decodeResource(_res, R.drawable.ship_4_left));
    _images.add(BitmapFactory.decodeResource(_res, R.drawable.ship_4_right));
    _images.add(BitmapFactory.decodeResource(_res, R.drawable.ship_5_left));
    _images.add(BitmapFactory.decodeResource(_res, R.drawable.ship_5_right));
    _images.add(BitmapFactory.decodeResource(_res, R.drawable.ship_6_left));
    _images.add(BitmapFactory.decodeResource(_res, R.drawable.ship_6_right));
    _firstBulletId = _images.size();
    _images.add(BitmapFactory.decodeResource(_res, R.drawable.bullet));
    _images.add(BitmapFactory.decodeResource(_res, R.drawable.opponent_bullet));
    _firstBgId = _images.size();
    _images.add(BitmapFactory.decodeResource(_res, R.drawable.background));
    _images.add(BitmapFactory.decodeResource(_res, R.drawable.redbackground));
    _images.add(BitmapFactory.decodeResource(_res, R.drawable.graybackground));
    _firstFireId = _images.size();
    _images.add(BitmapFactory.decodeResource(_res, R.drawable.fire));
    _images.add(BitmapFactory.decodeResource(_res, R.drawable.grayfire));
    _firstOcularId = _images.size();
    _images.add(BitmapFactory.decodeResource(_res, R.drawable.ocular));
    _firstOpponentFocusId = _images.size();
    _images.add(BitmapFactory.decodeResource(_res, R.drawable.opponent_focus));
  }
  
  /* (non-Javadoc)
   * @see see.battle.Drawer#getShipId(int)
   */
  public int getShipId(int shipType) {
    return _firstShipId + shipType * 2;
  }
  
  /* (non-Javadoc)
   * @see see.battle.Drawer#getBulletId(int)
   */
  public int getBulletId(int bulletType) {
    return _firstBulletId + bulletType;
  }
  
  /* (non-Javadoc)
   * @see see.battle.Drawer#getBackgroundId(int)
   */
  public int getBackgroundId(int backgroundType) {
    return _firstBgId + backgroundType;
  }
  
  /* (non-Javadoc)
   * @see see.battle.Drawer#getFireId(int)
   */
  public int getFireId(int fireType) {
    return _firstFireId + fireType;
  }
  
  /* (non-Javadoc)
   * @see see.battle.Drawer#getOcularId()
   */
  public int getOcularId() {
    return _firstOcularId;
  }
  
  /* (non-Javadoc)
   * @see see.battle.Drawer#getOpponentFocusId()
   */
  public int getOpponentFocusId() {
    return _firstOpponentFocusId;
  }
  
  /* (non-Javadoc)
   * @see see.battle.Drawer#set_fireProcessor(see.battle.object.ObjectPool.FireProcessor)
   */
  public void set_fireProcessor(FireProcessor fireProcessor) {
    _view.set_fireProcessor(fireProcessor);
  }

  /* (non-Javadoc)
   * @see see.battle.Drawer#set_moveOcularProcessor(see.battle.object.ObjectPool.MoveOcularProcessor)
   */
  public void set_moveOcularProcessor(MoveOcularProcessor moveOcularProcessor) {
    _view.set_moveOcularProcessor(moveOcularProcessor);
  }

  /* (non-Javadoc)
   * @see see.battle.Drawer#set_drawProcessor(see.battle.object.ObjectPool.DrawProcessor)
   */
  public void set_drawProcessor(DrawProcessor drawProcessor) {
    _view.set_drawProcessor(drawProcessor);
  }

  /* (non-Javadoc)
   * @see see.battle.Drawer#drawScene()
   */
  public void drawScene() {
    _view.redraw();
  }
  
  /* (non-Javadoc)
   * @see see.battle.Drawer#draw(int, float, float)
   */
  public void draw(int objectId, float x, float y) {
    if (_canvas != null) {
      _canvas.drawBitmap(_images.get(objectId), 
          x * _widthInPx, y * _heightInPx, null);
    }
  }
  
  /* (non-Javadoc)
   * @see see.battle.Drawer#drawCurrentScore(int, int, int, int)
   */
  public void drawCurrentScore(int h1, int l1, int h2, int l2) {
    String s = "You have " + l1 + " left  " + 
    "|  Score " + h1;
    if (h2 >= 0) {
      s += ":" + h2 + " (left " + l2 + ")";
    }
    if (_canvas != null) {
      _canvas.drawText(s, _widthInPx * Const.statTextLeft, 
          _heightInPx * Const.statTextTop, _p);    
    }
  }
}
